package server.service;

import com.qqcommon.Message;
import com.qqcommon.MessageType;
import com.qqcommon.User;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wty
 * @date 2022/10/25 15:25
 * 服务端，监听客户端端口，并且保持通信
 */
@SuppressWarnings({"all"})
public class QQServer {
    private User user = null;
    private ServerSocket serverSocket = null;

    // 创建集合存放用户；类似于数据库
    // 这些合法用户登录，才能登录成功
    //private static HashMap<String, User> validUsers = new HashMap<>();
    // 可以处理并发的ConcurrentHashMap  线程安全的
    private static ConcurrentHashMap<String, User> validUsers = new ConcurrentHashMap<>();

    // 静态代码块初始化
    static {
        validUsers.put("100", new User("100", "123456"));
        validUsers.put("200", new User("200", "123456"));
        validUsers.put("300", new User("300", "123456"));
        validUsers.put("400", new User("400", "666666s"));
        validUsers.put("至尊宝", new User("至尊宝", "666666"));
        validUsers.put("紫霞仙子", new User("紫霞仙子", "666666"));
    }

    // 验证用户登录是否有效的方法
    private boolean isValid(String userID, String password) {
        if (validUsers.containsKey(userID)) {
            User user = validUsers.get(userID);
            if (password.equals(user.getPassword())) {
                return true;
            }
        }
        return false;
    }

    public QQServer() {
        try {
            System.out.println("服务端在9999端口等待监听…………");
            // 端口号可以写到配置文件中
            serverSocket = new ServerSocket(9999);

            // 启动推送新闻的线程
            new Thread(new SendNewsToEveryone()).start();

            // 因为服务端需要一直监听，所以这里用while循环
            while (true) {

                Socket socket = serverSocket.accept();
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                Object o = objectInputStream.readObject();
                // 读取客户端发送的User对象
                User user = (User) o;

                // 创建一个Message对象(成功与否都要发送信息)，准备回复客户端
                Message message = new Message();

                // 获取对象输出流
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());

                // 验证用户
                if (isValid(user.getUserID(), user.getPassword())) {
                    System.out.println("用户" + user.getUserID() + "登录成功");

                    // 合法用户
                    message.setType(MessageType.MESSAGE_LOGIN_SUCCEED);
                    // 把成功回复回去
                    objectOutputStream.writeObject(message);

                    //socket.shutdownOutput();

                    // 启动线程循环监听
                    // ServerConnectionThread serverConnectionThread = new ServerConnectionThread(user.getUserID(), socket, o);
                    ServerConnectionThread serverConnectionThread = new ServerConnectionThread(user.getUserID(), socket);
                    serverConnectionThread.start();
                    ManageServerConnectServiceThread.add(user.getUserID(), serverConnectionThread);

                    // 推送离线消息 (这里一定要放在这个地方再推送)
                    new OffLineMessageThread().start();
                } else {
                    System.out.println("用户" + user.getUserID() + "登录验证失败");
                    // 非法用户
                    message.setType(MessageType.MESSAGE_LOGIN_FAILURE);
                    // 把失败回复回去
                    objectOutputStream.writeObject(message);
                    socket.close();
                }


                //objectOutputStream.close();
                // objectInputStream.close();
                // socket.close();
            } // while循环
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("QQServer线程退出");
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }

        }
    }

}
